<template>
  <div class="container">
    <input
      type="file"
      @change="handleUpload"
      accept="image/*"
      class="upload-input"
    />
    <div
      class="canvas-container"
      @click="handleCanvasClick"
      tabindex="0"
      @keydown.delete="deleteSelectedMarker"
    >
      <img
        v-if="imageUrl"
        :src="imageUrl"
        ref="imageRef"
        class="uploaded-image"
        @load="handleImageLoad"
      />
      <div
        v-for="(marker, index) in markers"
        :key="index"
        class="marker"
        :class="{ selected: selectedMarkerIndex === index }"
        :style="{
          left: `${marker.x}px`,
          top: `${marker.y}px`,
        }"
        @click.stop="selectMarker(index)"
      >
        <div class="marker-dot"></div>
        <div class="marker-text">{{ marker.sku }}</div>
        <button
          v-if="selectedMarkerIndex === index"
          class="delete-marker-btn"
          @click.stop="deleteMarker(index)"
        >
          ×
        </button>
      </div>
    </div>

    <!-- 商品绑定表单 -->
    <div v-if="showForm" class="product-form" :style="formStyle">
      <input v-model="currentSku" placeholder="输入SKU" class="sku-input" />
      <button @click="bindSKU" class="bind-btn">绑定</button>
    </div>

    <button @click="exportData" class="export-btn">导出数据</button>
    <pre v-if="exportedData">{{ exportedData }}</pre>
  </div>
</template>
  
  <script setup>
import { ref, nextTick, onMounted, onUnmounted } from "vue";

const imageRef = ref(null);
const imageUrl = ref("");
const showForm = ref(false);
const currentSku = ref("");
const currentPosition = ref({ x: 0, y: 0 });
const markers = ref([]);
const exportedData = ref(null);
const formStyle = ref({ left: "0", top: "0" });
const imageSize = ref({ width: 0, height: 0 });
const selectedMarkerIndex = ref(-1);

// 图片上传处理
const handleUpload = (e) => {
  const file = e.target.files[0];
  if (!file) return;

  // 释放之前的URL
  if (imageUrl.value) {
    URL.revokeObjectURL(imageUrl.value);
  }

  markers.value = [];
  exportedData.value = null;
  selectedMarkerIndex.value = -1;

  // 创建临时URL
  imageUrl.value = URL.createObjectURL(file);
};

// 图片加载完成
const handleImageLoad = () => {
  if (imageRef.value) {
    imageSize.value = {
      width: imageRef.value.naturalWidth,
      height: imageRef.value.naturalHeight,
    };
  }
};

// 画布点击事件
const handleCanvasClick = (e) => {
  // 如果点击的是标记点区域，不处理
  if (e.target.closest(".marker")) return;

  if (!imageUrl.value) return;

  const rect = e.currentTarget.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  // 确保点击在图片范围内
  if (x < 0 || y < 0 || x > rect.width || y > rect.height) return;

  selectedMarkerIndex.value = -1; // 取消已选中的标记
  showForm.value = true;
  currentPosition.value = { x, y };

  formStyle.value = {
    left: `${e.clientX + 10}px`,
    top: `${e.clientY}px`,
    position: "fixed",
  };
};

// 选择标记点
const selectMarker = (index) => {
  selectedMarkerIndex.value = index;
  showForm.value = false;
};

// 绑定SKU
const bindSKU = () => {
  if (!currentSku.value.trim()) {
    alert("请输入SKU！");
    return;
  }

  markers.value.push({
    x: currentPosition.value.x,
    y: currentPosition.value.y,
    sku: currentSku.value,
  });

  showForm.value = false;
  currentSku.value = "";
  selectedMarkerIndex.value = -1;
};

// 删除标记点
const deleteMarker = (index) => {
  markers.value.splice(index, 1);
  selectedMarkerIndex.value = -1;
};

// 键盘删除选中的标记点
const deleteSelectedMarker = () => {
  if (selectedMarkerIndex.value >= 0) {
    deleteMarker(selectedMarkerIndex.value);
  }
};

// 导出数据
const exportData = () => {
  if (markers.value.length === 0) {
    alert("请先添加标记点！");
    return;
  }

  exportedData.value = JSON.stringify(
    markers.value.map((marker) => ({
      x: Math.round(marker.x),
      y: Math.round(marker.y),
      sku: marker.sku,
      // 添加相对于图片实际尺寸的比例
      relativeX:
        imageSize.value.width > 0
          ? (marker.x / imageRef.value.clientWidth) * imageSize.value.width
          : 0,
      relativeY:
        imageSize.value.height > 0
          ? (marker.y / imageRef.value.clientHeight) * imageSize.value.height
          : 0,
    })),
    null,
    2
  );
};

// 组件卸载时释放URL
onUnmounted(() => {
  if (imageUrl.value) {
    URL.revokeObjectURL(imageUrl.value);
  }
});
</script>
  
  <style scoped>
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.canvas-container {
  position: relative;
  width: 600px;
  height: 400px;
  margin: 20px 0;
  border: 1px solid #ddd;
  overflow: hidden;
  outline: none; /* 移除焦点边框 */
}

.uploaded-image {
  max-width: 100%;
  max-height: 100%;
  display: block;
}

.marker {
  position: absolute;
  transform: translate(-50%, -50%);
  z-index: 10;
  cursor: pointer;
}

.marker.selected .marker-dot {
  background-color: #ff0;
  box-shadow: 0 0 0 2px rgba(255, 255, 0, 0.5);
}

.marker-dot {
  width: 20px;
  height: 20px;
  background-color: red;
  border-radius: 50%;
  border: 2px solid white;
  transition: all 0.2s;
}

.marker-text {
  margin-top: 5px;
  padding: 2px 5px;
  background: white;
  border-radius: 3px;
  font-size: 12px;
  white-space: nowrap;
}

.delete-marker-btn {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 20px;
  height: 20px;
  background: #ff4444;
  color: white;
  border: none;
  border-radius: 50%;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  z-index: 11;
}

.product-form {
  position: absolute;
  background: white;
  padding: 10px;
  border: 1px solid #ccc;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.export-btn {
  margin-top: 20px;
  padding: 8px 16px;
  background: #4caf50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.2s;
}

.export-btn:hover {
  background: #3d8b40;
}

.upload-input {
  margin-bottom: 10px;
}
</style>